import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';

import ZSTD from 'node-zstandard';
import XXHash from 'xxhashjs';

import { dirCache } from '../../../../lib/global.js';


export const toHexL = function(number, pad = 0, reverse = true) {
	const hex = BigInt(number).toString(16).toUpperCase().padStart(pad, '0');

	const hexArr = [];
	for(let i = 0; i < hex.length; i += 2) {
		hexArr.push(hex.slice(i, i + 2));
	}

	return reverse ? hexArr.reverse().join('') : hexArr.join('');
};

const pathTempZSTD = resolve(dirCache, 'zstd');
export const unZstd = async function(path, buffer, returnBuffer = false) {
	writeFileSync(pathTempZSTD, buffer);

	await new Promise((resolve, reject) => ZSTD.decompress(pathTempZSTD, path, err => err ? reject(err) : resolve()));

	if(returnBuffer) { return readFileSync(path); }
};

const units = ['字节', 'KB', 'MB', 'GB', 'TB'];
export const toSize = function(number) {
	let level = 0;
	while(number > 1023 && level < 4) { number /= 1024; level++; }

	return `${Number(number.toFixed(2))} ${units[level]}`;
};

export const wadHash = function(str, isHex = false) {
	if(typeof str != 'string') { throw 'argv not String'; }

	const strLower = str.toLowerCase();
	const strBuffer = Buffer.from(strLower);
	const hashBuffer = Buffer.from(XXHash.h64(strBuffer, 0).toString(16).padStart(16, '0').split(/(?<=^(?:.{2})+)(?!$)/).map(a => Number(`0x${a}`)));
	const hashHexRaw = hashBuffer.toString('hex');
	const hashBigInt = BigInt(`0x${hashHexRaw}`);

	if(isHex) {
		const hashBigIntSlice = hashBigInt;
		const hashHex = hashBigIntSlice.toString('16').toUpperCase();
		const hashHexPad = hashHex.padStart(10, '0');

		return hashHexPad;
	}

	return hashBigInt;
};
export const pad0 = function(id, size = 3) { return String(id).padStart(size, '0'); };